/*
多线程可以让Java同时运行多个个线程的程序
 */

public class MyThread extends Thread{

    public void run(){
        for(int i = 0;i < 20;i++){
            System.out.println(i);
        }
        String name = getName();    //获取线程的名字

        Thread t = Thread.currentThread();     //获取线程的详细信息
    }

}


public class RunnableImpl implements Runnable{

    public void run(){
        for(int i = 0;i < 20;i++){
            System.out.println(i);                    //创建一个类然后重写Runnable接口的方法
        }
    }

}



public class demo() {

    public static void main(String[] args) {
        MyThread mt = new MyThread();           //第一种方法
        mt.setName("nihao");                   //设置线程名称
        mt.start();         //开启了多线程

        for (int i = 0; i < 20; i++) {
            System.out.println(i);               //输出时按照抢占的优先度排列顺序
            thread.sleep(1000);                    //睡眠后再运行，单位为毫秒
        }


        new MyThread("nibuhao");              //新开一个线程并且命名   （第二种）

        RunnableImpl run = new RunnableImpl();       //新建一个类
        Thread t = new Thread(run);                  //创建Thread类对象
        t.start;                                     //开启线程


        new Thread() {
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(i);                    //重写父类的run方法
                }
            }.

            start();                                             //匿名类开始线程任务


            Runnable r = new Runnable() {
                public void run() {
                    for (int i = 0; i < 20; i++) {
                        System.out.println(i);                    //重写父类的run方法
                    }
                }
            };
        new

            Thread(r).start;                                  //Runnable直接开始线程任务
        }

    }
}

/*
线程安全对策
 */


public class Ticket implements Runnable{

    Object obj = new Object();                    //创建一个锁对象

    public void run(obj/*this也是可以的*/){
        synchronized(){                   //将代码放入同步代码块中，就可以避免多次执行
            for (int i = 0; i < 20; i++) {
                System.out.println(i);
            }
        }
    }

}

public class Ticket implements Runnable{

    public void run(obj){//将代码放入同步代码块中，就可以避免多次执行
            a();
        }

    public synchronized void a(){
        for (int i = 0; i < 20; i++) {
            System.out.println(i);
        }
    }                                             //创建一个同步方法来实现同步，效果是一样的

}

//java.util.concurrent.Locks.lock接口             使用Lock锁实现线程安全

public class Ticket implements Runnable{

    Lock l = new ReentrantLock();                    //创建一个ReentrantLock对象

    public void run(){
        l.lock();            //加锁
        for (int i = 0; i < 20; i++) {
            System.out.println(i);
        }
        l.unlock();         //解锁
    }

}



public class demo2{

    public static void main(String[] args) {
        Ticket t = new Ticket();
        Thread t0 = new Thread(run);
        Thread t1 = new Thread(run);
        Thread t2 = new Thread(run);
        t0.start();
        t1.start();
        t2.start();
    }

}




//线程的等待和唤醒

public class demo3{

    public static void main(String[] args) {

        Object obj = new Object();

        new Thread(){
            public void run(){
                synchronized(obj){
                    System.out.println("告诉包子的种类和数量");
                    try{
                        obj.wait(/*里面可以填上等待时间*/);                       //告诉老板后睡眠
                    }catch(InterruptedException e){
                        e.printStackRTrace();
                    }
                    System.out.println("开吃");
                }
            }.start();
        }

        new Thread(){
            public void run(){
                try {
                    Thread.sleep(5000);
                }catch(InterruptedException e){
                    e.printStackRTrace();
                }
                synchronized(obj){
                    System.out.println("做好包子");
                    obj.notify();                     //做好包子后唤醒（有多个线程的话随机唤醒）
                    //obj.notifyAll();      叫醒所有睡眠的线程
                }
            }.start();
        }
    }
}



//wait和notify只能在调用同一个锁对象时才能使用
